package org.cfk.asyncdownloadtutorial.downloadhandler;

import lombok.Data;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.cfk.asyncdownloadtutorial.annotation.AsyncDownloadJobWorker;
import org.cfk.asyncdownloadtutorial.dto.ExcelDownloadRequest;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Component
public class ExcelDownloadHandler {

    private static final Random RANDOM = new Random();
    private static final String[] FIRST_NAMES = {"张", "李", "王", "刘", "陈", "杨", "黄", "赵", "吴", "周"};
    private static final String[] LAST_NAMES = {"伟", "芳", "娜", "秀英", "敏", "静", "丽", "强", "磊", "军"};
    private static final String[] CITIES = {"北京", "上海", "广州", "深圳", "杭州", "南京", "成都", "武汉", "西安", "重庆"};

    /**
     * Excel文件导出处理方法
     * 
     * @param params 导出参数
     * @param file 输出文件
     */
    @AsyncDownloadJobWorker("excel")
    public void handleExcelDownload(ExcelDownloadRequest params, File file) throws IOException {
        // 创建ExcelWriter
        try (var excelWriter = EasyExcel.write(file).build()) {
            // 遍历处理每个Sheet
            for (int sheetIndex = 0; sheetIndex < params.getSheets().size(); sheetIndex++) {
                var sheetConfig = params.getSheets().get(sheetIndex);
                var sheet = new WriteSheet();
                sheet.setSheetNo(sheetIndex);
                sheet.setSheetName(sheetConfig.getSheetName());

                // 生成表头数据
                List<String> headers = sheetConfig.getColumns().stream()
                        .map(ExcelDownloadRequest.ColumnConfig::getColumnName)
                        .collect(Collectors.toList());

                // 写入表头
                excelWriter.write(Collections.singletonList(headers), sheet);

                // 生成并写入数据行
                List<List<String>> dataRows = IntStream.range(0, sheetConfig.getRowCount())
                        .mapToObj(i -> generateRandomRow(sheetConfig.getColumns()))
                        .collect(Collectors.toList());
                excelWriter.write(dataRows, sheet);
            }
        }
    }

    private List<String> generateRandomRow(List<ExcelDownloadRequest.ColumnConfig> columns) {
        return columns.stream()
                .map(column -> generateRandomValue(column.getDataType()))
                .collect(Collectors.toList());
    }

    private String generateRandomValue(String type) {
        switch (type.toLowerCase()) {
            case "number":
                return String.valueOf(RANDOM.nextInt(10000));
            case "decimal":
                return String.format("%.2f", RANDOM.nextDouble() * 1000);
            case "date":
                return LocalDate.now().minusDays(RANDOM.nextInt(365))
                        .format(DateTimeFormatter.ISO_DATE);
            case "datetime":
                return LocalDateTime.now().minusDays(RANDOM.nextInt(365))
                        .format(DateTimeFormatter.ISO_DATE_TIME);
            case "name":
                return LAST_NAMES[RANDOM.nextInt(LAST_NAMES.length)] +
                        FIRST_NAMES[RANDOM.nextInt(FIRST_NAMES.length)];
            case "boolean":
                return String.valueOf(RANDOM.nextBoolean());
            case "city":
                return CITIES[RANDOM.nextInt(CITIES.length)];
            default:
                return "数据" + RANDOM.nextInt(100);
        }
    }

}